package database

import (
	"fmt"
	"reflect"
	"strings"

	"gorm.io/gorm"
)

// SoftDeleteFilter 逻辑删除过滤器结构体
type SoftDeleteFilter struct {
	// 排除的表名列表（需要查询已删除数据的表）
	ExcludeTables []string
	// 排除的模型类型列表
	ExcludeModels []string
}

// NewSoftDeleteFilter 创建新的逻辑删除过滤器
func NewSoftDeleteFilter() *SoftDeleteFilter {
	return &SoftDeleteFilter{
		ExcludeTables: []string{"sys_audit_log", "system_log"}, // 审计日志等可能需要查询已删除数据
		ExcludeModels: []string{"AuditLog", "SystemLog"},       // 对应的模型类型
	}
}

// AddExcludeTable 添加排除的表名
func (sf *SoftDeleteFilter) AddExcludeTable(tableName string) {
	sf.ExcludeTables = append(sf.ExcludeTables, tableName)
}

// AddExcludeModel 添加排除的模型类型
func (sf *SoftDeleteFilter) AddExcludeModel(modelName string) {
	sf.ExcludeModels = append(sf.ExcludeModels, modelName)
}

// ShouldApplySoftDeleteFilter 判断是否应该应用逻辑删除过滤器
func (sf *SoftDeleteFilter) ShouldApplySoftDeleteFilter(db *gorm.DB) bool {
	// 检查表名是否在排除列表中
	if db.Statement != nil && db.Statement.Table != "" {
		for _, excludeTable := range sf.ExcludeTables {
			if strings.EqualFold(db.Statement.Table, excludeTable) {
				return false
			}
		}
	}

	// 检查模型类型是否在排除列表中
	if db.Statement != nil && db.Statement.Model != nil {
		modelType := reflect.TypeOf(db.Statement.Model)
		if modelType.Kind() == reflect.Ptr {
			modelType = modelType.Elem()
		}

		modelName := modelType.Name()
		for _, excludeModel := range sf.ExcludeModels {
			if strings.EqualFold(modelName, excludeModel) {
				return false
			}
		}
	}

	// 检查模型是否有DeletedAt字段
	if db.Statement != nil && db.Statement.Model != nil {
		modelType := reflect.TypeOf(db.Statement.Model)
		if modelType.Kind() == reflect.Ptr {
			modelType = modelType.Elem()
		}

		// 检查模型是否有DeletedAt字段
		if _, hasField := modelType.FieldByName("DeleteAt"); !hasField {
			return false
		}
	}

	return true
}

// ApplySoftDeleteFilter 应用逻辑删除过滤器
func (sf *SoftDeleteFilter) ApplySoftDeleteFilter(db *gorm.DB) *gorm.DB {
	if !sf.ShouldApplySoftDeleteFilter(db) {
		return db
	}

	// 检查是否已经应用了删除条件（防止重复添加）
	if db.Statement != nil && db.Statement.SQL.String() != "" {
		// 检查SQL语句中是否已包含delete_at IS NULL
		sqlStr := db.Statement.SQL.String()
		if strings.Contains(sqlStr, "delete_at IS NULL") {
			return db
		}
	}

	// 智能判断是否是多表查询
	if sf.isMultiTableQuery(db) {
		// 对于多表查询，只在明确的情况下添加条件
		// 或者不添加，让开发者手动处理
		return db
	}

	// 对于单表查询，安全地添加 delete_at IS NULL 条件
	return db.Where("delete_at IS NULL")
}

// isMultiTableQuery 判断是否为多表查询
func (sf *SoftDeleteFilter) isMultiTableQuery(db *gorm.DB) bool {
	if db.Statement == nil {
		return false
	}

	// 检查是否包含JOIN语句
	sqlStr := db.Statement.SQL.String()
	if sqlStr != "" && strings.Contains(strings.ToUpper(sqlStr), "JOIN") {
		return true
	}

	// 检查是否手动设置了JOIN条件
	if len(db.Statement.Joins) > 0 {
		return true
	}

	// 检查是否通过Table()方法设置了复杂表表达式
	if db.Statement.TableExpr != nil {
		exprStr := fmt.Sprintf("%v", db.Statement.TableExpr)
		if strings.Contains(strings.ToUpper(exprStr), "JOIN") || strings.Contains(exprStr, ",") {
			return true
		}
	}

	return false
}

// SkipSoftDeleteFilter 跳过逻辑删除过滤器
func SkipSoftDeleteFilter() *gorm.DB {
	// 直接返回原始数据库实例，不应用任何过滤器
	return DB
}

// WithSoftDeleteFilter 创建带逻辑删除过滤器的数据库实例
func WithSoftDeleteFilter(db *gorm.DB) *gorm.DB {
	sf := NewSoftDeleteFilter()
	return db.Scopes(sf.ApplySoftDeleteFilter)
}

// GetDBWithSoftDeleteFilter 获取带逻辑删除过滤器的数据库实例
func GetDBWithSoftDeleteFilter() *gorm.DB {
	return WithSoftDeleteFilter(DB)
}
